package com.qs.sckill.listener;

import com.qs.sckill.entity.SckillOrder;
import com.qs.sckill.entity.User;
import com.qs.sckill.service.GoodsService;
import com.qs.sckill.service.OrderService;
import com.qs.sckill.service.SckillService;
import com.qs.sckill.vo.GoodsVo;
import com.qs.sckill.vo.SckillMessage;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.amqp.core.ExchangeTypes;
import org.springframework.amqp.rabbit.annotation.Exchange;
import org.springframework.amqp.rabbit.annotation.Queue;
import org.springframework.amqp.rabbit.annotation.QueueBinding;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;

/**
 * 监听RabbitMQ消息队列，接收消息秒杀发送的队列消息，生成订单、秒杀订单
 *
 * @author qinyupeng
 * @since 2019-08-01 16:35:33
 */
@Component
public class GoodsSckillListener {

    private final static Logger logger = LoggerFactory.getLogger(GoodsSckillListener.class);

    @Resource
    private OrderService orderService;

    @Resource
    private SckillService sckillService;

    @Resource
    private GoodsService goodsService;


    /**
     * 从消息队列中取出秒杀请求发送过来的数据，处理秒杀请求，完成生成订单、秒杀订单、减库存等系列操作
     *
     * @param sckillMessage RabbitMQ消息队列中传递的消息对象，包含用户和商品id信息
     * @author qinyupeng
     * @since 2019-08-02 14:41:01
     */
    @RabbitListener(
            bindings = @QueueBinding(
                    //将exchange中的消息绑定到指定队列中
                    value = @Queue(value = "goods.sckill.queue", durable = "true"),
                    //监听的exchange名
                    exchange = @Exchange(
                            value = "goods.sckill.exchange",
                            ignoreDeclarationExceptions = "true",
                            type = ExchangeTypes.TOPIC
                    ),
                    //匹配key
                    key = "goods.doSckill"
            )
    )
    public void listenGoodsSckill(SckillMessage sckillMessage) {
        System.out.println("===>>>开始接收消息，处理秒杀成功加入队列请求：");
        System.out.println(sckillMessage);
        User user = sckillMessage.getUser();
        if (user == null) {
            logger.error("user is null");
            return;
        }

        String goodsId = sckillMessage.getGoodsId();
        if (StringUtils.isBlank(goodsId)) {
            logger.error("goodsId is null");
            return;
        }

        //获取商品库存，库存不足，直接返回
        GoodsVo goods = goodsService.getGoodsVoByGoodsId(goodsId);
        Integer stockCount = goods.getStockCount();
        if (stockCount <= 0) {
            logger.error("秒杀商品库存不足！");
            return;
        }

        //判断当前用户是否已经秒杀到订单，有，则之间返回
        SckillOrder sckillOrder = orderService.getSckillOrderByUserIdAndGoodsId(user.getId(), goodsId);
        if (sckillOrder != null) {
            logger.error("该用户已经秒杀过该商品了，不能重复秒杀！");
            return;
        }

        try {
            //处理秒杀订单、减库存操作
            sckillService.doSckill(user, goods);
        } catch (Exception e) {
            logger.error(e.getMessage());
        }
    }


    /**
     * 测试监听
     */
    @RabbitListener(
            bindings = @QueueBinding(
                    value = @Queue(value = "test.queue", durable = "true"),
                    exchange = @Exchange(
                            value = "test.exchange",
                            ignoreDeclarationExceptions = "true",
                            type = ExchangeTypes.TOPIC),
                    key = "add-opt"
            )
    )
    public void testListen(SckillMessage sckillMessage) {
        System.out.println("开始监听接收：");
        System.out.println("===>>" + sckillMessage);
    }
}
